package org.jeecg.modules.business.strategy;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseArea;
import org.jeecg.modules.basic.warehouse.mapper.WmsBasicWarehouseAreaMapper;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTaskMaterial;
import org.jeecg.modules.business.outbound.mapper.WmsOutReceiptTaskMapper;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskMaterialService;
import org.jeecg.modules.business.strategy.entity.MesSite;
import org.jeecg.modules.business.strategy.entity.OutReceiptStrategyParam;
import org.jeecg.modules.business.strategy.service.IMesSiteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : lumingyi
 * @date : 2023/11/24 8:58
 * @description : 出库策略
 * @Version : 1.0
 */
@Component
@Slf4j
public class OutReceiptStrategy {

    @Value(value = "${wms.config.strategy.outReceiptWarehouseCode:0}")
    private String outReceiptWarehouseCode;

    @Autowired
    private WmsBasicWarehouseAreaMapper warehouseAreaMapper;
    @Autowired
    private WmsOutReceiptTaskMapper outReceiptTaskMapper;
    @Autowired
    private IMesSiteService mesSiteService;
    @Autowired
    private ISysBaseAPI iSysBaseAPI;
    @Autowired
    private IWmsOutReceiptTaskMaterialService outReceiptTaskMaterialService;

    /**
     * 横剪叫料(条料)
     *
     * @return
     */
    public WmsBasicWarehouseArea outReceiptStrategy(OutReceiptStrategyParam param) {
        try {
            // 第一优选策略：存在最多被叫卷料的库区优先
            List<String> areaIds = outReceiptTaskMapper.listMaxArea(param.getTaskId());
            if (areaIds.size() == 1) {
                WmsBasicWarehouseArea area = warehouseAreaMapper.selectById(areaIds.get(0));
                return area;
            }
            if (areaIds.size() == 0) {
                return null;
            }
            // 第二优先策略：
            List<WmsOutReceiptTaskMaterial> materials = outReceiptTaskMaterialService.selectByMainId(param.getTaskId());
            WmsBasicWarehouseArea area = this.getAreaBySite(param.getSite(), materials.get(0).getWmsBasicWarehouseId());
            if (area != null && areaIds.contains(area.getId())) {
                return area;
            }
            MesSite one = mesSiteService.getOne(new LambdaQueryWrapper<MesSite>()
                    .eq(MesSite::getAskMaterialSite, param.getSite())
                    .last("limit 1"));
            if (one == null) {
                return null;
            }
            List<WmsBasicWarehouseArea> areas = warehouseAreaMapper.selectBatchIds(areaIds);
            // 200#横剪线叫料主备料区优先顺序：A＞B＞C
            if (one.getLineName().contains("200")) {
                return this.getArea("A", "B", "C", areas);
            }
            // 300#横剪线叫料主备料区优先顺序：B＞C＞A
            if (one.getLineName().contains("300")) {
                return this.getArea("B", "C", "A", areas);
            }
            // 400#横剪线叫料主备料区优先顺序：C＞B＞A
            if (one.getLineName().contains("400")) {
                return this.getArea("C", "B", "A", areas);
            }
        } catch (Exception e) {
            log.error("出库策略报错，入参为:"+ JSON.toJSONString(param) +"，报错为:", e );
        }
        return null;
    }

    private WmsBasicWarehouseArea getArea(String first, String second, String third, List<WmsBasicWarehouseArea> areas) {
        List<String> areaIds = areas.stream().map(WmsBasicWarehouseArea::getId).collect(Collectors.toList());
        List<WmsBasicWarehouseArea> firstList = areas.stream().filter(a -> {
            String[] split = a.getCode().split("-");
            return split[split.length -1].contains(first);
        }).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(firstList) && areaIds.contains(firstList.get(0).getId())) {
            return firstList.get(0);
        }
        List<WmsBasicWarehouseArea> secondList = areas.stream().filter(a -> {
            String[] split = a.getCode().split("-");
            return split[split.length -1].contains(second);
        }).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(secondList) && areaIds.contains(secondList.get(0).getId())) {
            return secondList.get(0);
        }
        List<WmsBasicWarehouseArea> thirdList = areas.stream().filter(a -> {
            String[] split = a.getCode().split("-");
            return split[split.length -1].contains(third);
        }).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(thirdList) && areaIds.contains(thirdList.get(0).getId())) {
            return thirdList.get(0);
        }
        return null;
    }

    /**
     * 根据站点找库区
     * @param site
     * @param warehouseId
     * @return
     */
    private WmsBasicWarehouseArea getAreaBySite(String site, String warehouseId) {
        if (StringUtils.isBlank(site)) {
            return null;
        }
        List<DictModel> sites = iSysBaseAPI.getDictItems("cross_cut_material_site");    // 生产站点
        List<DictModel> siteList = sites.stream().filter(a -> site.equals(a.getText())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(siteList)) {
            return null;
        }
        List<WmsBasicWarehouseArea> areas = warehouseAreaMapper.selectList(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, warehouseId));
        List<WmsBasicWarehouseArea> collect = areas.stream().filter(a -> StringUtils.isNotBlank(a.getProductSite()) && Arrays.asList(a.getProductSite().split(",")).contains(siteList.get(0).getValue())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
            return null;
        }
        return collect.get(0);
    }
}
